﻿using System;
using System.Configuration;
using System.IO;
using System.Web.Services.Protocols;

namespace CrmRulo
{
    /// <summary>
    /// Main entry point for CrmRulo
    /// </summary>
    class Program
    {
        private static string _inputDirectory;
        private static string _outputDirectory;
        private static string _action;
        private static string _connectionName = "crm";
        private static bool _version4;

        static void Main(string[] args)
        {
            try
            {
                ParseArguments(args);
                switch (_action)
                {
                    case "localize":
                        LocalizeReports("en");
                        break;
                    case "upload":
                        UploadReports();
                        break;
                    case "both":
                        LocalizeReports("en");
                        UploadReports();
                        break;
                }
            }
            catch (SoapException soapEx)
            {
                Console.WriteLine(soapEx.Detail.OuterXml);
                Console.WriteLine(soapEx.StackTrace);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
            finally
            {
                Console.WriteLine(@"CrmRulo: Done.");
                Console.ReadLine();
            }
        }

        /// <summary>
        /// Analize the command line arguments
        /// </summary>
        /// <param name="args">The array of arguments</param>
        static void ParseArguments(string[] args)
        {
            _inputDirectory = ".";
            _action = "both";

            for (int i = 0; i < args.Length; i++)
            {
                if (args[i] == "-i")
                    _inputDirectory = args[++i];
                if (args[i] == "-o")
                    _outputDirectory = args[++i];
                if (args[i] == "-a")
                    _action = args[++i];
                if (args[i] == "-c")
                    _connectionName = args[++i];
                if (args[i] == "-v4")
                    _version4 = true;
            }

            if (_action == "upload") // Upload only
                _outputDirectory = _inputDirectory;
            else if (String.IsNullOrEmpty(_outputDirectory))
                _outputDirectory = _inputDirectory + "/publish";
        }

        /// <summary>
        /// Creates a temporary folder for localized reports.
        /// Calls the report localizer with the specified language as the default language
        /// </summary>
        /// <param name="baseLanguage">Language code string, i.e. 'en', 'es', 'de'</param>
        static void LocalizeReports(string baseLanguage)
        {
            var reportFileNames = new DirectoryInfo(_inputDirectory).GetFiles("*.rdl");
            if (reportFileNames.Length == 0)
            {
                Console.WriteLine(@"No report files were found. Exiting.");
                return;
            }

            if (!Directory.Exists(_outputDirectory))
                Directory.CreateDirectory(_outputDirectory);
            var reportsLocalizer = new ReportsLocalizer(_inputDirectory, _outputDirectory, baseLanguage);
            var languages = reportsLocalizer.FindAvailableLanguagesForReport(_inputDirectory + "\\reports.rdl", false);
            foreach (var language in languages)
                reportsLocalizer.CompileResourceFileForReport("reports.rdl", language);

            foreach (var report in reportFileNames)
            {
                foreach (var language in reportsLocalizer.FindAvailableLanguagesForReport(report.FullName, true))
                {
                    reportsLocalizer.CompileResourceFileForReport(report.FullName, language);
                    reportsLocalizer.Localize(report.FullName, language);
                }
            }
        }

        /// <summary>
        /// Uploads the reports found in the output directory
        /// </summary>
        private static void UploadReports()
        {
            string versionString = _version4 ? "4.0" : "2011";
            Console.WriteLine(@"Connecting to CRM {0} using connection string '{1}'", versionString, _connectionName);
            if (ConfigurationManager.ConnectionStrings[_connectionName] == null)
                throw new ConfigurationErrorsException("Connection string not found: " + _connectionName);
            var connectionSettings = ConfigurationManager.ConnectionStrings[_connectionName];
            IReportManager reportManager;
            if (_version4)
                reportManager = new v4.ReportManager(connectionSettings.ConnectionString);
            else
                reportManager = new v2011.ReportManager(_connectionName);
            var sinc = new ReportsSynchronizer(reportManager);
            sinc.UploadAllReports(_outputDirectory);
        }
    }
}